package com.tiancheng.trade.merchant.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tiancheng.trade.commom.core.data.PageInfo;
import com.tiancheng.trade.commom.core.data.Result;
import com.tiancheng.trade.commom.core.enums.PaymentChannelEnum;
import com.tiancheng.trade.commom.core.exception.error.BusinessErrorInfoEnum;
import com.tiancheng.trade.commom.web.feign.PaymentFeignService;
import com.tiancheng.trade.commom.web.model.response.PaymentChannelResponseDTO;
import com.tiancheng.trade.merchant.enums.CostTypeEnum;
import com.tiancheng.trade.merchant.enums.MerchantScenarioEnum;
import com.tiancheng.trade.merchant.enums.SettlementStatusEnum;
import com.tiancheng.trade.merchant.exception.BusinessException;
import com.tiancheng.trade.merchant.feign.ISettlementRuleFeignService;
import com.tiancheng.trade.merchant.feign.SettlementService;
import com.tiancheng.trade.merchant.mapper.MerchantMapper;
import com.tiancheng.trade.merchant.mapper.ProductMapper;
import com.tiancheng.trade.merchant.model.Merchant;
import com.tiancheng.trade.merchant.model.Product;
import com.tiancheng.trade.merchant.service.IProductService;
import com.tiancheng.trade.merchant.util.ExcelUtil;
import com.tiancheng.trade.merchant.util.IdGenerateUtil;
import com.tiancheng.trade.merchant.util.UserUtils;
import com.tiancheng.trade.merchant.vo.merchant.GetProductVO;
import com.tiancheng.trade.merchant.vo.product.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.DigestUtils;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;

/**
 * 商户
 */
@Service
public class ProductService implements IProductService {

    /**
     * 允许通过接口导入清分规则的场景
     */
    private static final List<String> OPEN_SETTLE_RULE_SOURCE = new ArrayList<String>() {{
        add(MerchantScenarioEnum.TOURISM_INVESTMENT.getCode());
    }};
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private MerchantMapper merchantMapper;
    @Autowired
    private ISettlementRuleFeignService settlementRuleFeignService;
    @Autowired
    private SettlementService settlementFeignService;
    @Autowired
    private PaymentFeignService paymentFeignService;
    @Autowired
    private IdGenerateUtil idGenerateUtil;

    @Override
    public FindProductDetailResponseVO findDetailById(Long id) throws BusinessException {
        Product product = productMapper.selectById(id);
        Assert.notNull(product, "该产品不存在或已删除");
        Assert.isTrue(product.getIsDelete()==0, "该产品已删除");
        FindProductDetailResponseVO productVO = new FindProductDetailResponseVO();
        // 补全枚举文本
        product.setScenarioCn(MerchantScenarioEnum.getDescByCode(product.getScenario()));
        product.setCostTypeCn(CostTypeEnum.getDescByCode(String.valueOf(product.getCostType())));
        product.setPaymentChannelCn(PaymentChannelEnum.getByCode(product.getPaymentChannel()).get().getDesc());

        BeanUtils.copyProperties(product, productVO);
        if (StringUtils.isNotEmpty(product.getMerchantCode())) {
            QueryWrapper<Merchant> conditions = new QueryWrapper<>();
            conditions.eq("is_delete", "0");
            conditions.eq("merchant_code", product.getMerchantCode());
            Merchant merchant = merchantMapper.selectOne(conditions);
            if (null != merchant) {
                productVO.setMerchantName(merchant.getMerchantName());
            }
        }
        BigDecimal num = new BigDecimal("100");
        productVO.setCostTypeCn(CostTypeEnum.getDescByCode(String.valueOf(productVO.getCostType())));
        if (CostTypeEnum.FIXED.getCode().equals(String.valueOf(productVO.getCostType()))) {
            productVO.setCostPrice(productVO.getCostPrice().divide(num, BigDecimal.ROUND_HALF_UP));
        }

        Result<List<SettlementRuleVO>> settlementRuleResult = settlementRuleFeignService.findSettlementRuleList(product.getProductCode(),null);
        if (CollectionUtils.isNotEmpty(settlementRuleResult.getData())) {
            List<SettlementRuleVO> ruleList = settlementRuleResult.getData();
            List<SettlementRuleVO> ruleList0 = ruleList.stream().filter(x -> x.getSettlementStatus().equals(SettlementStatusEnum.NOTEFFECTIVE.getCode())).collect(Collectors.toList());
            List<SettlementRuleVO> ruleList1 = ruleList.stream().filter(x -> x.getSettlementStatus().equals(SettlementStatusEnum.EFFECTIVE.getCode())).collect(Collectors.toList());
            List<SettlementRuleVO> ruleList2 = ruleList.stream().filter(x -> x.getSettlementStatus().equals(SettlementStatusEnum.EXPIRED.getCode())).collect(Collectors.toList());
            List<SettlementRuleVO> ruleList3 = ruleList.stream().filter(x -> x.getSettlementStatus().equals(SettlementStatusEnum.CANCEL.getCode())).collect(Collectors.toList());
            List<SettlementRuleVO> newList = new ArrayList<>();
            newList.addAll(ruleList1);
            newList.addAll(ruleList0);
            newList.addAll(ruleList2);
            newList.addAll(ruleList3);
            productVO.setSettlementRuleList(newList);
        }
        return productVO;
    }

    @Override
    public PageInfo<Product> findPageList(FindProductPageListVO product) throws BusinessException {
        Page<Product> page = new Page<>();
        page.setCurrent(product.getCurrentPage());
        page.setSize(product.getPageSize());
        IPage<Product> pageresult = productMapper.findPageList(page, product);
        PageInfo.Pagination pagination = new PageInfo.Pagination(product.getCurrentPage(), product.getPageSize(), page.getTotal());
        List<Product> pageList = pageresult.getRecords();
        Result<List<PaymentChannelResponseDTO>> channelBOList = paymentFeignService.getAllChannel();
        List<PaymentChannelResponseDTO> channelList = new ArrayList<>();
        if (channelBOList.getRet() == 0) {
            channelList = channelBOList.getData();
        }
        BigDecimal num = new BigDecimal("100");
        for (Product p : pageList) {
            // 补全枚举文本
            p.setScenarioCn(MerchantScenarioEnum.getDescByCode(p.getScenario()));
            p.setCostTypeCn(CostTypeEnum.getDescByCode(String.valueOf(p.getCostType())));
            if (CostTypeEnum.FIXED.getCode().equals(String.valueOf(p.getCostType())) && null != p.getCostPrice()) {
                p.setCostPrice(p.getCostPrice().divide(num, BigDecimal.ROUND_HALF_UP));
            }
            if (CollectionUtils.isNotEmpty(channelList)) {
                if (StringUtils.isNotEmpty(p.getPaymentChannel()) && CollectionUtils.isNotEmpty(channelList)) {
                    List<PaymentChannelResponseDTO> filterList = channelList.stream().filter(c -> c.getPaymentChannelCode().equals(p.getPaymentChannel())).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(filterList)) {
                        p.setPaymentChannelCn(filterList.get(0).getPaymentChannelName());
                    }
                }
            }
        }
        return new PageInfo<>(pageList, pagination);
    }

    @Override
    public int removeById(Long id) throws BusinessException {
        Product product = productMapper.selectById(id);

        Assert.notNull(product, "删除失败，该产品不存在或已删除");

        Result<List<SettlementRuleVO>> settlementRuleResult = settlementRuleFeignService.findSettlementRuleList(product.getProductCode(),"1");

        Assert.isTrue(settlementRuleResult.getRet() == 0, "删除失败，获取清分规则配置失败，请稍后重试");

        // 查询是否配有清分规则
        boolean isHasRule = settlementRuleResult.getData() == null || settlementRuleResult.getData().isEmpty();
        Assert.isTrue(isHasRule, "已有关联清分规则，不允许删除");

        product.setIsDelete(1);
        product.setLastUpdBy(UserUtils.currentUserId());//删除人
        product.setLastUpdDt(LocalDateTime.now());

        return productMapper.updateById(product);
    }

    @Override
    public int update(UpdateProductVO productVO) throws BusinessException {
        Product product = new Product();
        product.setId(productVO.getId());
        product.setMerchantCode(productVO.getMerchantCode());
        product.setProductName(productVO.getProductName());
        product.setProductDetail(productVO.getProductDetail());
        product.setScenario(productVO.getScenario());
        product.setProductCodeBusiness(productVO.getProductCodeBusiness());
        product.setCostType(productVO.getCostType());
        if (CostTypeEnum.FIXED.getCode().equals(String.valueOf(productVO.getCostType()))) {
            BigDecimal num = new BigDecimal("100");
            product.setCostPrice(productVO.getCostPrice().multiply(num));
        } else {
            product.setCostPrice(productVO.getCostPrice());
        }
        product.setPaymentChannel(productVO.getPaymentChannel());
        product.setLastUpdDt(LocalDateTime.now());
        product.setLastUpdBy(UserUtils.currentUserId());
        Product prod = productMapper.selectById(productVO.getId());
        if (null != prod) {
            // 判断商品编码是否被修改
            if (StringUtils.isNotEmpty(productVO.getProductCode())) {
                BusinessErrorInfoEnum.PRODUCT_EXISTS_ERROR.assertIsTrue(Objects.equals(productVO.getProductCode(), prod.getProductCode()));
            }
            // 判断业务测商品编码是否被修改
            if (StringUtils.isNotEmpty(productVO.getProductCodeBusiness())) {
                LambdaQueryWrapper<Product> busiQueryWrapper = new LambdaQueryWrapper<Product>().eq(Product::getProductCodeBusiness, product.getProductCodeBusiness())
                        .eq(Product::getIsDelete, 0).ne(Product::getId, prod.getId());
                List<Product> busiProducts = this.productMapper.selectList(busiQueryWrapper);
                BusinessErrorInfoEnum.PRODUCT_BUSINESS_EXISTS_ERROR.assertIsTrue(CollectionUtils.isEmpty(busiProducts));
            }
            PaymentProductVO paymentProductVO = new PaymentProductVO();
            paymentProductVO.setProduct_code(prod.getProductCode());
            paymentProductVO.setProduct_code_business(product.getProductCodeBusiness());
            String jsonStr = JSONArray.toJSON(paymentProductVO).toString();
            settlementFeignService.updateSubOrderProduct(jsonStr);
        }
        return productMapper.updateById(product);
    }

    public void test() {
        QueryWrapper<Product> conditions = new QueryWrapper<>();
        conditions.eq("product_code", "");
        List<Product> mm = productMapper.selectList(conditions);
        for (Product product : mm) {
            String content = product.getProductName() + String.valueOf(product.getCreatedDt()).substring(0, 19);
            product.setProductCode(DigestUtils.md5DigestAsHex(content.getBytes()).toUpperCase());
            productMapper.updateById(product);
        }
    }

    @Override
    public int create(CreateProductVO productVO) throws BusinessException {
        Product product = new Product();
        product.setMerchantCode(productVO.getMerchantCode());
        product.setProductCode(productVO.getProductCode());
        product.setProductName(productVO.getProductName());
        product.setProductDetail(productVO.getProductDetail());
        product.setScenario(productVO.getScenario());
        product.setProductCodeBusiness(productVO.getProductCodeBusiness());
        product.setCostType(productVO.getCostType());
        if (CostTypeEnum.FIXED.getCode().equals(String.valueOf(productVO.getCostType()))) {
            BigDecimal num = new BigDecimal("100");
            product.setCostPrice(productVO.getCostPrice().multiply(num));
        } else {
            product.setCostPrice(productVO.getCostPrice());
        }
        product.setPaymentChannel(productVO.getPaymentChannel());
        product.setCreatedDt(LocalDateTime.now());
        product.setCreatedBy(UserUtils.currentUserId());
        // 如果没有指定productCode 则自动生成
        if (StringUtils.isEmpty(product.getProductCode())) {
            // 拼接creatTime时间戳(秒)后进行MD5运算 防止同名
            String content = product.getProductName() + String.valueOf(product.getCreatedDt()).substring(0, 19);
            product.setProductCode(DigestUtils.md5DigestAsHex(content.getBytes()).toUpperCase());
        }
        LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<Product>().eq(Product::getProductCode, product.getProductCode())
                .eq(Product::getIsDelete, 0);
        List<Product> products = this.productMapper.selectList(queryWrapper);

        BusinessErrorInfoEnum.PRODUCT_EXISTS_ERROR.assertIsTrue(CollectionUtils.isEmpty(products));

        if (StringUtils.isNotEmpty(productVO.getProductCodeBusiness())) {
            // 业务测商品编码判断重复
            LambdaQueryWrapper<Product> busiQueryWrapper = new LambdaQueryWrapper<Product>().eq(Product::getProductCodeBusiness, product.getProductCodeBusiness())
                    .eq(Product::getIsDelete, 0);
            List<Product> busiproducts = this.productMapper.selectList(busiQueryWrapper);
            BusinessErrorInfoEnum.PRODUCT_BUSINESS_EXISTS_ERROR.assertIsTrue(CollectionUtils.isEmpty(busiproducts));
        }
        PaymentProductVO paymentProductVO = new PaymentProductVO();
        paymentProductVO.setProduct_code(product.getProductCode());
        paymentProductVO.setProduct_code_business(product.getProductCodeBusiness());
        String jsonStr = JSONArray.toJSON(paymentProductVO).toString();
        settlementFeignService.updateSubOrderProduct(jsonStr);
        return productMapper.insert(product);
    }

    @Override
    public List<Product> findPaymentChannelByProductCodes(List<String> strList) throws BusinessException {
        return productMapper.findPaymentChannelByProductCodes(strList).stream().collect(
                collectingAndThen(toCollection(() -> new TreeSet<>(Comparator.comparing(Product::getProductCodeBusiness))), ArrayList::new)
        );
    }

    @Override
    public List<Product> findPayChannelByCodeBusiness(List<String> strList) throws BusinessException {
        return productMapper.findPayChannelByCodeBusiness(strList);
    }

    @Override
    public Long getProductQty(GetProductVO productVO) throws BusinessException {
        QueryWrapper<Product> conditions = new QueryWrapper<>();
        conditions.eq("is_delete", "0");
        conditions.eq("merchant_code", productVO.getMerchantCode());
        conditions.eq("payment_channel", productVO.getPayChannel());
        return productMapper.selectCount(conditions);
    }

    @Override
    public List<Product> findProductCodeBusiness(FindProductPageListVO product) throws BusinessException {
        QueryWrapper<Product> conditions = new QueryWrapper<>();
        conditions.eq("is_delete", "0");
        conditions.eq("product_code_business", product.getProductCodeBusiness());
        if (null != product.getId()) {
            conditions.ne("id", product.getId());
        }
        return productMapper.selectList(conditions);
    }

    /**
     * 商户信息导出
     *
     * @param merchantVO
     * @param request
     * @param response
     * @throws IOException
     */
    public void export(FindProductPageListVO merchantVO, HttpServletRequest request, HttpServletResponse response) throws IOException {

        List<Product> plist = productMapper.findPageList(merchantVO);
        List<ProductExpVO> list = new ArrayList<>();
        BigDecimal num = new BigDecimal("100");
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        if (CollectionUtils.isNotEmpty(plist)) {
            plist.forEach(a -> {
                ProductExpVO productVO = new ProductExpVO();
                if (CostTypeEnum.FIXED.getCode().equals(String.valueOf(a.getCostType()))) {
                    a.setCostPrice(a.getCostPrice().divide(num, BigDecimal.ROUND_HALF_UP));
                }
                a.setScenario(MerchantScenarioEnum.getDescByCode(a.getScenario()));
                BeanUtils.copyProperties(a, productVO);
                productVO.setCreatedDt(df.format(a.getCreatedDt()));
                list.add(productVO);
            });
        }
        List<Map<String, Object>> mapList = listConvert(list);

        String fileName = "产品信息.xlsx";
        String[] title = {"产品名称", "产品编码", "所属商户", "产品详情", "业务场景", "业务侧产品编码", "成本价格", "创建时间"};
        Workbook workbook = ExcelUtil.buildWorkbook("产品信息", title, mapList);
        ExcelUtil.exportExcle(request, response, workbook, fileName);
    }

    @Override
    public Product getProductInfo(String productId) {
        QueryWrapper<Product> conditions = new QueryWrapper<>();
        conditions.eq("product_code", productId);
        List<Product> mm = productMapper.selectList(conditions);
        return CollectionUtils.isEmpty(mm) ? null : mm.get(0);
    }

    @Transactional
    @Override
    public List<CreateProductResVO> openCreate(OpenCreateProductVO productVO) {
        BusinessErrorInfoEnum.SETTLE_RULE_RULE_ORDER_SOURCE_NOT_SUPPORT.assertIsTrue(OPEN_SETTLE_RULE_SOURCE.contains(productVO.getOrderSource()));
        List<Merchant> merchants = merchantMapper.getMerchantByMerCode(Collections.singletonList(productVO.getMerchantCode()));
        BusinessErrorInfoEnum.MERCHANT_NOT_EXISTENCE.assertIsTrue(CollectionUtils.isNotEmpty(merchants));

        // 判断有没有重复添加的商品
        QueryWrapper<Product> conditions = new QueryWrapper<>();
        conditions.eq("is_delete", "0");
        //conditions.eq("merchant_code", productVO.getMerchantCode());
        conditions.in("product_code_business", productVO.getProducts().stream().map(OpenCreateProductVO.Product::getProductCodeBusiness).collect(Collectors.toList()));
        List<Product> mm = productMapper.selectList(conditions);
        BusinessErrorInfoEnum.PRODUCT_EXISTS_ERROR.assertIsTrue(CollectionUtils.isEmpty(mm));

        List<CreateProductResVO> res = new ArrayList<>();
        List<Product> products = new ArrayList<>(productVO.getProducts().size());
        for (OpenCreateProductVO.Product pv : productVO.getProducts()) {
            Product product = new Product();
            product.setMerchantCode(productVO.getMerchantCode());
            product.setProductCode(idGenerateUtil.getProductCode());
            product.setProductName(pv.getProductName());
            product.setProductDetail(pv.getProductDetail());
            product.setScenario(productVO.getOrderSource());
            product.setProductCodeBusiness(pv.getProductCodeBusiness());
            product.setCostType(1);
            product.setCostPrice(new BigDecimal(0));
            product.setCreatedDt(LocalDateTime.now());
            product.setIsDelete(0);

            if (StringUtils.isNotEmpty(pv.getPaymentChannel())) {
                product.setPaymentChannel(pv.getPaymentChannel());
            } else {
                //TODO 现在只有银联，如果新增了支付通道需要修改这里
                product.setPaymentChannel("ums");
            }
            product.setCreatedDt(LocalDateTime.now());
            product.setCreatedBy("open api order_source:" + productVO.getOrderSource());
            products.add(product);
            res.add(new CreateProductResVO(product.getProductCodeBusiness(), product.getProductCode()));
        }
        productMapper.saveBatch(products);
        return res;
    }

    @Transactional
    @Override
    public void openDelete(OpenDeleteProductVO productVO) {
        BusinessErrorInfoEnum.SETTLE_RULE_RULE_ORDER_SOURCE_NOT_SUPPORT.assertIsTrue(OPEN_SETTLE_RULE_SOURCE.contains(productVO.getOrderSource()));
        productMapper.deleteOpenBatch(productVO.getProducts());
        /*final Result<?> result = settlementRuleFeignService.openDeleteRule(productVO);
        BusinessErrorInfoEnum.SETTLE_RULE_RULE_DELETE_FAIL.assertIsTrue(result.getRet().equals(0));*/

    }

    @Override
    public void openUpdate(OpenUpdateProductVO productVO) {
        BusinessErrorInfoEnum.SETTLE_RULE_RULE_ORDER_SOURCE_NOT_SUPPORT.assertIsTrue(OPEN_SETTLE_RULE_SOURCE.contains(productVO.getOrderSource()));
        QueryWrapper<Product> conditions = new QueryWrapper<>();
        conditions.eq("merchant_code", productVO.getMerchantCode());
        conditions.eq("product_code", productVO.getProductCode());
        List<Product> mm = productMapper.selectList(conditions);
        BusinessErrorInfoEnum.PRODUCT_EXISTS_ERROR.assertIsTrue(CollectionUtils.isNotEmpty(mm));

        final Product product = new Product();
        product.setId(mm.get(0).getId());
        product.setProductName(productVO.getProductName());
        if (StringUtils.isNotEmpty(productVO.getProductDetail())) {
            product.setProductDetail(productVO.getProductDetail());
        }
        productMapper.updateById(product);
    }

    @Override
    public void openDeleteByMerchant(OpenDeleteProductByMerchantVO openDeleteProductVO) {
        BusinessErrorInfoEnum.SETTLE_RULE_RULE_ORDER_SOURCE_NOT_SUPPORT.assertIsTrue(OPEN_SETTLE_RULE_SOURCE.contains(openDeleteProductVO.getOrderSource()));
        List<Merchant> merchants = merchantMapper.getMerchantByMerCode(Collections.singletonList(openDeleteProductVO.getMerchantCode()));
        BusinessErrorInfoEnum.MERCHANT_NOT_EXISTENCE.assertIsTrue(CollectionUtils.isNotEmpty(merchants));
        QueryWrapper<Product> conditions = new QueryWrapper<>();
        conditions.eq("is_delete", "0");
        conditions.eq("merchant_code", openDeleteProductVO.getMerchantCode());
        List<Product> mm = productMapper.selectList(conditions);
        if(CollectionUtils.isNotEmpty(mm)){
            List<OpenDeleteProductVO.Product> products=new ArrayList<>(mm.size());
            for (Product product : mm) {
                final OpenDeleteProductVO.Product p = new OpenDeleteProductVO.Product();
                p.setMerchantCode(openDeleteProductVO.getMerchantCode());
                p.setProductCode(product.getProductCode());
                products.add(p);
            }
            productMapper.deleteOpenBatch(products);
            /*OpenDeleteProductVO productVO=new OpenDeleteProductVO();
            productVO.setOrderSource(openDeleteProductVO.getOrderSource());
            productVO.setProducts(products);
            final Result<?> result = settlementRuleFeignService.openDeleteRule(productVO);
            BusinessErrorInfoEnum.SETTLE_RULE_RULE_DELETE_FAIL.assertIsTrue(result.getRet().equals(0));*/
        }
    }

    @Override
    public int deleteByProductCode(String productCode) {
        final QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_code",productCode);
        final Product product = productMapper.selectOne(queryWrapper);

        Assert.notNull(product, "删除失败，该产品不存在或已删除");

        Assert.isTrue(product.getIsDelete()==1,"商品不允许删除");
        Result<List<SettlementRuleVO>> settlementRuleResult = settlementRuleFeignService.findSettlementRuleList(product.getProductCode(),"1");

        Assert.isTrue(settlementRuleResult.getRet() == 0, "删除失败，获取清分规则配置失败，请稍后重试");

        // 查询是否配有清分规则
        boolean isHasRule = settlementRuleResult.getData() == null || settlementRuleResult.getData().isEmpty();
        Assert.isTrue(isHasRule, "已有关联清分规则，不允许删除");
        return productMapper.deleteById(product.getId());
    }

    /**
     * 数据转换
     *
     * @param list
     * @return
     */
    private List<Map<String, Object>> listConvert(List<ProductExpVO> list) {
        List<Map<String, Object>> list_map = new ArrayList<>();
        try {
            for (ProductExpVO t : list) {
                Field[] fields = t.getClass().getDeclaredFields();
                Map<String, Object> m = new LinkedHashMap<>();
                for (Field field : fields) {
                    String keyName = field.getName();
                    PropertyDescriptor pd = new PropertyDescriptor(keyName, t.getClass());
                    Method getMethod = pd.getReadMethod();// 获得getter方法
                    Object o = getMethod.invoke(t);// 执行get方法返回一个Object
                    m.put(keyName, o);
                }
                list_map.add(m);
            }
            return list_map;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
